/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef LIBCOAP_CLIENT_H
#define LIBCOAP_CLIENT_H
#include <string>
#include <list>
#include "base.h"
struct TrackToken {
    coap_binary_t *token;
    int observe;
};

const int MAX_PARAM_NUM = 64;

enum class CoapCode { SUCCESS = 0, OTHER_ERROR = 1, NETWORK_ERROR = 2, URL_ERROR = 3};
class Client {
public:
    static napi_value Request(napi_env env, napi_callback_info info);
    static napi_value SetFormat(napi_env env, napi_callback_info info);
    static napi_value SetPayload(napi_env env, napi_callback_info info);
    static napi_value SetPort(napi_env env, napi_callback_info info);
    static napi_value SetToken(napi_env env, napi_callback_info info);
    static napi_value SetWaitSecond(napi_env env, napi_callback_info info);
    static napi_value SetObsSecond(napi_env env, napi_callback_info info);
    static napi_value SetRepeatCount(napi_env env, napi_callback_info info);
    static napi_value JsConstructor(napi_env env, napi_callback_info info);
    static napi_value AddOption(napi_env env, napi_callback_info info);
    static napi_value SetMid(napi_env env, napi_callback_info info);
    static napi_value SetPayloadBinary(napi_env env, napi_callback_info info);
    static napi_value RegisterOption(napi_env env, napi_callback_info info);
    std::string classIdStr;
    coap_optlist_t *optList = nullptr;
    int format = -1;
    int defaultWaitTime = 10;
    double waitSeconds = defaultWaitTime; /* default timeout in seconds */
    size_t repeatCount = 1;
    char *portStr;
    unsigned char tokenData[8];
    coap_binary_t baseToken = {0, tokenData};
    coap_string_t payload = {0, nullptr}; /* optional payload to send */
    std::list<std::string> clientResultList;
    char serverUri[2048] = {0};
    int quit = 0;
    CoapCode code = CoapCode::OTHER_ERROR;
    int obsMsReset = 0;
    int doingObserve = 0;
    unsigned int waitMs = 0;
    int obsStarted = 0;
    unsigned int obsSeconds = 30; /* default observe time */
    unsigned int obsMs = 0;       /* timeout for current subscription */
    int flags = 0;
    TrackToken *trackedTokens = nullptr;
    size_t trackedTokensCount = 0;
    int flagsBlock = 0x01;
    // Request URI.
    coap_uri_t uri;
    int repeatDelayMs = 1000;
    int time = 1000;
    /* reading is done when this flag is set */
    int ready = 0;
    /* processing a block response when this flag is set */
    int doingGettingBlock = 0;
    int singleBlockRequested = 0;
    uint32_t blockMode = COAP_BLOCK_USE_LIBCOAP;
    int reliable = 0;
    int isMcast = 0;
    uint32_t csmMaxMessageSize = 0;
    unsigned char msgType = COAP_MESSAGE_CON; /* usually, requests are sent confirmable */
    unsigned char method = 1; /* the method we are using in our requests */
    coap_block_t block = {.num = 0, .m = 0, .szx = 6};
    std::string tokenStr;
    coap_binary_t payloadBinary = {0, nullptr}; /* optional payloadBinary to send */
    int mid = 0;
    bool needRemoteInfo = false;
    std::string remoteIp;
    std::list<std::uint16_t> options;
    bool needCallBack = false;
    napi_threadsafe_function _callbackFunc = nullptr;
};

#endif // LIBCOAP_CLIENT_H